package com.netty;

import com.util.Gloabl;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;
import io.netty.handler.codec.string.StringDecoder;

/**
 * netty客户端
 * 
 * @author micro
 *
 */
public class NettyClient {

	public static void main(String[] args) {
		new NettyClient().run();
	}

	public void run() {

		try {
			// 配置客户端NIO线程组
			Bootstrap bootstrap = new Bootstrap();
			EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

			try {
				bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
						.handler(new ChannelInitializer<SocketChannel>() {
							@Override
							protected void initChannel(SocketChannel ch) throws Exception {
								/***** 解决粘包问题，用ByteBuf来做分隔符，有_mayi字符的就发，否则不发。(一般推荐这种方式) *****/
								// ByteBuf buf = Unpooled.copiedBuffer("_mayi".getBytes());
								// ch.pipeline().addLast(new DelimiterBasedFrameDecoder(1024, buf));

								/***** 设置字符串 *****/
								// ch.pipeline().addLast(new StringDecoder());

								/***** 传对象 ******/
								// 用ObjectEncoder和ObjectDecoder.(网上参考传对象方式)
								// ch.pipeline().addLast(
								// new ObjectEncoder(),
								// new ObjectDecoder(Integer.MAX_VALUE, ClassResolvers.cacheDisabled(null)),
								// new NettyClientHandler());

								// 用序列化对象.(参考蚂蚁架构导师案例代码)
								ch.pipeline().addLast(
										MarshallingCodeCFactory.buildMarshallingDecoder(),
										MarshallingCodeCFactory.buildMarshallingEncoder(), 
										new NettyClientHandler());
							}
						});

				// 发起异步连接操作
				ChannelFuture future = bootstrap.connect(Gloabl.host, Gloabl.port).sync();
				// 当代客户端链路关闭
				future.channel().closeFuture().sync();
			} finally {
				// 优雅退出，释放NIO线程组
				eventLoopGroup.shutdownGracefully();
			}
		} catch (Exception e) {
			// TODO: handle exception
			System.out.println("客户端异常：[" + e.getMessage() + "]");
		}

	}

}
